package com.tencreat.account.controller.app;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.lock.annotation.Lock4j;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.google.common.collect.Lists;
import com.tencreat.common.annotation.Log;
import com.tencreat.common.core.HttpResult;
import com.tencreat.common.core.controller.BaseController;
import com.tencreat.common.core.domain.BaseEntity;
import com.tencreat.common.enums.BusinessType;
import com.tencreat.domain.account.AccountWithdrawAudit;
import com.tencreat.domain.account.AccountWithdrawInfo;
import com.tencreat.domain.account.CommonWithdrawConfig;
import com.tencreat.domain.account.dto.AccountWithdrawInfo2DTO;
import com.tencreat.domain.account.dto.AccountWithdrawInfoDTO;
import com.tencreat.domain.account.dto.ApiWithdrawDTO;
import com.tencreat.domain.account.dto.CommonWithdrawConfigDTO;
import com.tencreat.domain.account.vo.AccountWithdrawInfoVO;
import com.tencreat.service.account.IAccountWithdrawAuditService;
import com.tencreat.service.account.IAccountWithdrawInfoService;
import com.upay.sdk.FastJsonUtils;
import com.upay.sdk.cashier.bindcard.executer.BindCardExecuter;
import com.upay.sdk.exception.HmacVerifyException;
import com.upay.sdk.exception.ResponseException;
import com.upay.sdk.exception.UnknownException;
import com.upay.sdk.executer.ResultListenerAdpater;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 用户提现基础信息Controller
 *
 * @author tencreat
 * @date 2021-11-25
 */
@Api(tags = "94-用户绑卡基础信息api")
@RestController
@RequestMapping("/api/withdraw/info")
@Slf4j
public class AccountWithdrawInfoController extends BaseController {
    @Autowired
    private IAccountWithdrawInfoService accountWithdrawInfoService;
    @Autowired
    private  IAccountWithdrawAuditService withdrawAuditService;


    /**
     * 获取用户提现基础信息详细信息
     */
    @ApiOperation(value = "获取用户提现基础信息详细信息")
    @PostMapping(value = "/getInfo")
    public HttpResult<AccountWithdrawInfo> getInfo() {
        AccountWithdrawInfo accountWithdrawInfo = accountWithdrawInfoService.lambdaQuery().eq(AccountWithdrawInfo::getUserId, getLoginCheck().getAccountLogin().getUuid()).eq(AccountWithdrawInfo::getType,0).oneOpt().orElse(new AccountWithdrawInfo());
        return HttpResult.ok(accountWithdrawInfo);
    }

    /**
     * 修改用户提现基础信息
     */
    @ApiOperation(value = "新增/修改用户提现基础信息")
    @Log(title = "用户提现基础信息", businessType = BusinessType.UPDATE)
    @PostMapping(value = "/saveOrUpdate")
    @Lock4j
    public HttpResult<Boolean> edit(@RequestBody AccountWithdrawInfo accountWithdrawInfo) {
        if (accountWithdrawInfo.getId() != null){
            return to(accountWithdrawInfoService.updateById(accountWithdrawInfo));
        }
        accountWithdrawInfo.setUserId(getLoginCheck().getAccountLogin().getUuid());
        accountWithdrawInfo.setBankCode(accountWithdrawInfo.getBankCode().trim());
        int count = accountWithdrawInfoService.lambdaQuery().eq(AccountWithdrawInfo::getUserId, accountWithdrawInfo.getUserId()).count();
        if (count > 0) {
            return HttpResult.error("请勿重复绑定");
        }
        return to(accountWithdrawInfoService.save(accountWithdrawInfo));
    }

    @ApiOperation(value = "提现")
    @PostMapping(value = "/withdraw")
    public HttpResult<String> withdraw(@RequestBody ApiWithdrawDTO vo) {

        return accountWithdrawInfoService.withdraw(vo, getLoginCheck());
    }

    @ApiOperation("提现明细")
    @PostMapping("queryWithdrawRecord")
    public HttpResult<List<AccountWithdrawAudit>> queryWithdrawRecord() {
        return HttpResult.ok(withdrawAuditService.lambdaQuery().eq(AccountWithdrawAudit::getUuid, getLoginCheck().getAccountLogin().getUuid()).orderByDesc(BaseEntity::getCreateTime).list());

    }
    @ApiOperation(value = "查询提现设置")
    @PostMapping(value = "/queryWithdrawConfig")
    public HttpResult<CommonWithdrawConfig> queryWithdrawConfig(@RequestBody CommonWithdrawConfigDTO dto) {
        return HttpResult.ok(accountWithdrawInfoService.selectWithdrawInfo(dto.getType(),dto.getUserType()));
    }

    /**
     * 充值绑定银行卡
     */
    @ApiOperation(value = "充值绑定银行卡")
    @Log(title = "充值绑定银行卡", businessType = BusinessType.UPDATE)
    @PostMapping(value = "/bandCart")
    public HttpResult<?> bandCart(@RequestBody AccountWithdrawInfoDTO accountWithdrawInfo) {
        accountWithdrawInfo.setUserId(getLoginCheck().getAccountLogin().getUuid());

        return HttpResult.ok(accountWithdrawInfoService.bandCart(accountWithdrawInfo));
    }

    /**
     * 充值绑定银行卡  确认
     */
    @ApiOperation(value = "充值绑定银行卡  确认")
    @Log(title = "充值绑定银行卡  确认", businessType = BusinessType.UPDATE)
    @PostMapping(value = "/confirmBandCart")
    public HttpResult<?> confirmBandCart(@RequestBody AccountWithdrawInfo2DTO accountWithdrawInfo) {

        return HttpResult.ok(accountWithdrawInfoService.confirmBandCart(accountWithdrawInfo.getKaptchaCode(),accountWithdrawInfo.getId()));
    }

    /**
     * 重发验证码
     */
    @ApiOperation(value = "重发验证码")
    @Log(title = "重发验证码", businessType = BusinessType.UPDATE)
    @PostMapping(value = "/getKaptcha")
    public HttpResult<?> getKaptcha(@RequestBody AccountWithdrawInfo2DTO accountWithdrawInfo) {

        return HttpResult.ok(accountWithdrawInfoService.getKaptcha(accountWithdrawInfo.getId()));
    }

    /**
     * 解绑 银行卡
     */
    @ApiOperation(value = "解绑 银行卡")
    @Log(title = "解绑 银行卡", businessType = BusinessType.UPDATE)
    @PostMapping(value = "/unbind")
    public HttpResult<?> unbind(@RequestBody AccountWithdrawInfo2DTO accountWithdrawInfo) {

        return HttpResult.ok(accountWithdrawInfoService.unbind(accountWithdrawInfo.getId()));
    }

    /**
     * 首信易绑定银行卡 回调
     *
     * @param 参数
     * @return 结果
     * @Author lx
     * @Date: 2022/07/04 02:20
     */
    @ApiOperation(value = "首信易绑定银行卡回调数据")
    @PostMapping("/bind/callback")
    @ApiIgnore
    public void sxyCallback(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        log.info("首信易银行卡回调数据："+req);
        BindCardExecuter executer = new BindCardExecuter();
        try{
            com.alibaba.fastjson15.JSONObject json = FastJsonUtils.convert(req.getInputStream());
            json.put("encryptKey",req.getHeader("encryptKey"));
            json.put("merchantId",req.getHeader("merchantId"));
            executer.callBack(json, new ResultListenerAdpater() {

                @Override
                public void success(com.alibaba.fastjson15.JSONObject jsonObject) {
                    log.info("绑卡成功！{}",jsonObject.toJSONString());
                    try {
                        if (jsonObject.getString("bindStatus").equals("SUCCESS")) {
                            LambdaUpdateChainWrapper<AccountWithdrawInfo> wrapper = accountWithdrawInfoService.lambdaUpdate().eq(AccountWithdrawInfo::getBindCardId, jsonObject.getString("bindCardId"))
                                    .set(AccountWithdrawInfo::getBindStatus, 1)
                                    .set(AccountWithdrawInfo::getUpdateTime, new Date());
                            wrapper.update();
                        }
                    } catch (Exception e) {
                        log.info("业务错误{}",e.toString());
                    }
                }

                @Override
                public void failure(com.alibaba.fastjson15.JSONObject jsonObject) {
                    log.info("绑卡失败！{}",jsonObject);
                    log.info(jsonObject.toJSONString());
                }
            });
        }
        catch(ResponseException e){
            log.error("响应异常{}",e.toString());
        }
        catch(HmacVerifyException e){
            log.error("签名验证异常{}",e.toString());
        }
        catch(UnknownException e){
            log.error("未知异常{}",e.toString());
        }

        PrintWriter out = resp.getWriter();

        out.print("SUCCESS");
    }

    @ApiOperation(value = "充值银行卡列表")
    @GetMapping(value = "/getBindList")
    public HttpResult<List<AccountWithdrawInfoVO>> queryListBank(Long type) {
        AccountWithdrawInfo accountWithdrawInfo = new AccountWithdrawInfo();
        accountWithdrawInfo.setUserId(getLoginCheck().getAccountLogin().getUuid());
        if (type != null) {
            // 杉德绑定
            accountWithdrawInfo.setType(type);
        }else {
            accountWithdrawInfo.setType(1L);
        }
        // 绑定状态 已绑定
        accountWithdrawInfo.setBindStatus(1L);

        List<AccountWithdrawInfo> accountWithdrawInfos = accountWithdrawInfoService.selectAccountWithdrawInfoList(accountWithdrawInfo);
        List<AccountWithdrawInfoVO> accountWithdrawInfoVOS = new ArrayList<>();
        if (accountWithdrawInfos != null){
            BeanUtils.copyProperties(accountWithdrawInfos,accountWithdrawInfoVOS);
        }

        return HttpResult.ok(accountWithdrawInfoVOS);
    }


    /**
     * 杉德 绑定银行卡
     */
    @ApiOperation(value = "杉德绑定银行卡")
    @Log(title = "杉德绑定银行卡", businessType = BusinessType.UPDATE)
    @PostMapping(value = "/sandBandCart")
    public HttpResult<?> sandBandCart(@RequestBody AccountWithdrawInfoDTO accountWithdrawInfo) {
        accountWithdrawInfo.setUserId(getLoginCheck().getAccountLogin().getUuid());

        return HttpResult.ok(accountWithdrawInfoService.sandBandCart(accountWithdrawInfo));
    }

    /**
     * 杉德绑定银行卡  确认
     */
    @ApiOperation(value = "杉德绑定银行卡  确认")
    @Log(title = "杉德绑定银行卡  确认", businessType = BusinessType.UPDATE)
    @PostMapping(value = "/sandConfirmBandCart")
    public HttpResult<?> sandConfirmBandCart(@RequestBody AccountWithdrawInfo2DTO accountWithdrawInfo) {

        return HttpResult.ok(accountWithdrawInfoService.sandConfirmBandCart(accountWithdrawInfo.getKaptchaCode(),accountWithdrawInfo.getId()));
    }
}
